﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Xml.Serialization;
using EpiNEXT.Core.Fields.Properties;

namespace EpiNEXT.Core.Fields
{
    /// <summary>
    /// A field type representing an input box that can accept free-text input.
    /// </summary>
    [Serializable()]
    public class TextBoxField : FieldWithSeparatePrompt, IInputField
    {
        /// <summary>
        /// Constructor
        /// </summary>
        public TextBoxField()
            : base()
        {
            InputFontSize = Constants.DEFAULT_INPUT_FONT_SIZE;
            PromptFontSize = Constants.DEFAULT_PROMPT_FONT_SIZE;
            PromptForegroundColor = new Color(255, 51, 51, 51);
            InputBorderThickness = new Thickness(1, 1, 1, 1);
            ForceUppercase = false;
            MaxLength = 255;
            ValuesMustBeUnique = false;
            AcceptsReturn = false;
            RegEx = String.Empty;
            RegExMessage = String.Empty;
            RegExMessageTranslations = new ObservableCollection<FieldTextPropertyTranslation>();
            InputMask = String.Empty;
            InputHeight = Double.NaN;
        }

        /// <summary>
        /// The .NET data type for this field
        /// </summary>
        public string DataType { get { return "System.String"; } }

        /// <summary>
        /// Gets/sets the maximum number of characters that can entered into this field
        /// </summary>
        [XmlElement]
        public int MaxLength { get; set; }

        /// <summary>
        /// Gets/sets whether the value in this field must be unique across all records
        /// </summary>
        [XmlElement]
        public bool ValuesMustBeUnique { get; set; }

        /// <summary>
        /// Gets/sets whether the field will force uppercase character input
        /// </summary>
        [XmlElement]
        public bool ForceUppercase { get; set; }

        /// <summary>
        /// Gets/sets whether the field accepts the RETURN key as valid input.
        /// </summary>
        [XmlElement]
        public bool AcceptsReturn { get; set; }

        /// <summary>
        /// Gets/sets the height of the input box
        /// </summary>
        //[XmlElement]
        //public double InputHeight { get; set; }

        /// <summary>
        /// Represents a regular expression that will be used to validate the input of the text box field
        /// </summary>
        [XmlElement]
        public string RegEx { get; set; }

        /// <summary>
        /// Represents the validation failure message that will be shown to the user when their input doesn't match the regular expression.
        /// </summary>
        [XmlElement]
        public string RegExMessage { get; set; }

        /// <summary>
        /// Represents a series of translations for the regular expression validation failure message
        /// </summary>
        [XmlArray("RegExMessageTranslations")]
        [XmlArrayItem("RegExMessageTranslation", typeof(FieldTextPropertyTranslation))]
        public ObservableCollection<FieldTextPropertyTranslation> RegExMessageTranslations { get; set; }

        /// <summary>
        /// The input mask to apply to this field
        /// </summary>
        [XmlElement]
        public string InputMask { get; set; }

        /// <summary>
        /// The ID of the field that this field is linked to in a "list/other" relationship.
        /// </summary>
        [XmlElement]
        public Guid OtherSourceId { get; set; }

        /// <summary>
        /// Gets whether or not this text box is used as an "other" attachment to a list-based field.
        /// </summary>
        [XmlIgnore]
        public bool IsOtherBox
        {
            get
            {
                if (OtherSourceId.Equals(new Guid("00000000000000000000000000000000")))
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
        }
    }
}
